﻿using Smokey.Shared.Constants;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
namespace Smokey.Shared.DataTransferObjects {
    public class ApplicationDto : DataTransferObjectBase {

        private string location;
        private string applicationName;
        private string email;
        private DateTime? lastRunDate;
        private ApplicationStatusConstant status;
        private int? quality;
        private DateTime? startDate;
        private DateTime? endDate;
        private int? noOfIterations;

        public int? ApplicationId { get; set; }

        [MaxLength(200)]
        [Required(AllowEmptyStrings = false)]
        public string Location {
            get {
                return location;
            }

            set {
                if (location != value) {
                    location = value;
                    OnPropertyChanged("Location");
                }
            }
        }

        [Required(AllowEmptyStrings = false)]
        [MaxLength(100)]
        public string ApplicationName {
            get {
                return applicationName;
            }

            set {
                if (applicationName != value) {
                    applicationName = value;
                    OnPropertyChanged("ApplicationName");
                }
            }
        }

        [MaxLength(100)]
        [Required(AllowEmptyStrings = false)]
        public string Email {
            get {
                return email;
            }
            set {
                if (email != value) {
                    email = value;
                    OnPropertyChanged("Email");
                }
            }
        }

        public DateTime? LastRunDate {
            get {
                return lastRunDate;
            }
            set {
                if (lastRunDate != value) {
                    lastRunDate = value;
                    OnPropertyChanged("LastRunDate");
                }
            }
        }

        public ApplicationStatusConstant Status {
            get {
                return status;
            }
            set {
                if (status != value) {
                    status = value;
                    OnPropertyChanged("Status");
                }
            }
        }

        public string StatusDescription {
            get {
                return Status != null ? Status.Description : string.Empty;
            }
        }

        public int? Quality {
            get {
                return quality;
            }
            set {
                if (quality != value) {
                    quality = value;
                    OnPropertyChanged("Quality");
                }
            }
        }

        public DateTime? StartDate {
            get {
                return startDate;
            }

            set {
                if (startDate != value) {
                    startDate = value;
                    OnPropertyChanged("StartDate");
                    ValidateScheduledRuns();
                }
            }
        }

        public DateTime? EndDate {
            get {
                return endDate;
            }

            set {
                if (endDate != value) {
                    endDate = value;
                    OnPropertyChanged("EndDate");
                    ValidateScheduledRuns();
                }
            }
        }

        public int? NoOfIterations {
            get {
                return noOfIterations;
            }

            set {
                if (noOfIterations != value) {
                    noOfIterations = value;
                    OnPropertyChanged("NoOfIterations");
                    ValidateScheduledRuns();
                }
            }
        }

        private async void ValidateScheduledRuns() {
            await Task.Factory.StartNew(() => {
                    var results = new List<ValidationResult>();
                    if (startDate.HasValue && endDate.HasValue && startDate > endDate) {
                        results.Add(new ValidationResult("Start date must not be before end date",
                            new List<string>() { "StartDate", "EndDate" }));
                    } else if (endDate.HasValue && !startDate.HasValue) {
                        results.Add(new ValidationResult("Start date must have a value if end date has one",
                            new List<string>() { "StartDate" }));
                    } else if (startDate.HasValue && !noOfIterations.HasValue) {
                        results.Add(new ValidationResult("Number of iterations must be specified.",
                            new List<string>() { "NoOfIterations" }));
                    }

                    HandleValidationResults(results);
                    OnErrorsChanged("StartDate");
                    OnErrorsChanged("EndDate");
                    OnErrorsChanged("NoOfIterations");
                });
        }
    }
}
